#include <avr/interrupt.h>
#include <avr/io.h>
#include "led.h"

#define MODE_NONE 0
#define MODE_FADE 1
#define MODE_BLINK 2

rgb current = {0,0,0}, start = {0,0,0}, next = {0,0,0};
unsigned int currenttime = 0, starttime = 0, endtime = 0, len = 0;
unsigned char mode = 0;

void int_set_color(rgb color)
{
	current = color;
	
	OCR0A = 255-color.b;
	OCR1A = 255-color.g;
	OCR1B = 255-color.r;
}

void lerp(unsigned int v)
{
	current.r = (next.r - start.r)*v/255+start.r;
	current.g = (next.g - start.g)*v/255+start.g;
	current.b = (next.b - start.b)*v/255+start.b;
	
	OCR0A = 255-current.b;
	OCR1A = 255-current.g;
	OCR1B = 255-current.r;
}

ISR(TIMER0_OVF_vect)
{
	currenttime++;
	
	switch(mode)
	{
		case MODE_NONE:
			break;
		case MODE_FADE:
			lerp(((currenttime-starttime)*255)/len);
			if(currenttime == endtime)
			{
				mode = MODE_NONE;
			}
			break;
		case MODE_BLINK:
			if((currenttime-starttime) > len)
			{
				int_set_color(next);
				rgb temp = next;
				next = start;
				start = temp;
				
				starttime = currenttime;
			}
			else
				int_set_color(start);
			break;
	}
}

void set_color(rgb color)
{
	mode = MODE_NONE;
	
	current = color;
	
	OCR0A = 255-color.b;
	OCR1A = 255-color.g;
	OCR1B = 255-color.r;
}

void fade_to_color(rgb color, unsigned short time)
{
	mode = MODE_FADE;
	
	start = current;
	next = color;
	
	starttime = currenttime;
	endtime = starttime+time;
	
	len = endtime - starttime;
}

void blink_color(rgb color, unsigned short time)
{
	mode = MODE_BLINK;
	
	start = current;
	next = color;
	
	starttime = currenttime;
	endtime = starttime+time;
	
	len = endtime - starttime;
}
